﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.Configuration;
using DevExpress.XtraCharts;
using FAMailUtils.MailGun;
using FAGateway.Common;

namespace FAGateway
{
    public partial class frmGateway_Amazon : DevExpress.XtraEditors.XtraForm
    {
        string AccessKey = System.Configuration.ConfigurationManager.AppSettings["AccessKey"];
        string SecrectKey = System.Configuration.ConfigurationManager.AppSettings["SecrectKey"];

        log4net.ILog logs_error = log4net.LogManager.GetLogger("ErrorRollingLogFileAppender");
        log4net.ILog logs_info = log4net.LogManager.GetLogger("InfoRollingLogFileAppender");
        log4net.ILog logs_scan = log4net.LogManager.GetLogger("ScanEmailAppender");
        static readonly object syncRoot = new object();
        AmazonCommon vEmail;
        double TotalSend, SendRate, Max24HourRate;

        public frmGateway_Amazon()
        {
            InitializeComponent();
        }

        private void frmGateway_Load(object sender, EventArgs e)
        {
            txtThread.Text = ConfigurationManager.AppSettings["DefaultThread"];
            bgw_sendMail.DoWork += bgw_sendMail_DoWork;
            vEmail = new AmazonCommon(AccessKey, SecrectKey);
            vEmail.GetQuotaInfo(out TotalSend, out SendRate, out Max24HourRate);
            txtSpeed.Text = SendRate + "";
            marqueeProgressBarControl1.Visible = false;
            txtBounceTopic.Text = ConfigurationManager.AppSettings["BounceTopic"];
            txtComplainTopic.Text = ConfigurationManager.AppSettings["ComplainTopic"];
        }

        private void btnDStart_Click(object sender, EventArgs e)
        {
            btnDStart.Enabled = false;
            btnDStop.Enabled = true;
            txtSecond.Enabled = false;

            timer_Dashboard.Interval = Convert.ToInt32(txtSecond.Text) * 1000;
            timer_Dashboard.Start();
        }

        private void LoadDashBoard()
        {
            vEmail.GetQuotaInfo(out TotalSend, out SendRate, out Max24HourRate);
            chartControl1.Series.Clear();
            Series series = new Series();
            SeriesPoint point = new SeriesPoint();
            point.Values = new double[] { TotalSend };
            point.Argument = "TotalSend";
            series.ChangeView(ViewType.Bar);
            series.Points.Add(point);
            chartControl1.Series.Add(series);

            series = new Series();
            point = new SeriesPoint();
            point.Values = new double[] { Max24HourRate };
            point.Argument = "Limit24Hours";
            series.ChangeView(ViewType.Bar);
            series.Points.Add(point);
            chartControl1.Series.Add(series);
        }

        private void timer_Dashboard_Tick(object sender, EventArgs e)
        {
            if (bgw_Dashboard.IsBusy) return;
            bgw_Dashboard.RunWorkerAsync();
        }

        private void btnDStop_Click(object sender, EventArgs e)
        {
            btnDStart.Enabled = true;
            btnDStop.Enabled = false;
            txtSecond.Enabled = true;
            timer_Dashboard.Stop();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            bgw_sendMail.CancelAsync();
            btnStart.Enabled = true;
            btnStop.Enabled = false;
            timer_sendMail.Stop();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            timer_sendMail.Enabled = true;
            btnStop.Enabled = true;
            btnStart.Enabled = false;
            timer_sendMail.Start();
        }

        void bgw_sendMail_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                List<SendItem> items = DataUtils.GetMail2Send();
                int cnt = 0;
                int totalCnt = items.Count;
                //Parallel.ForEach(items.AsParallel(), new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(txtThread.Text) }, item =>
                //{
                //    SendItem sendItem = vEmail.SendMail(item);
                //    string log = DateTime.Now+"-> Status: " + sendItem.isSend + ", id:" + sendItem.id + ", MailTo: " + sendItem.To + ", mailFrom: " + sendItem.From + ", Name: " + sendItem.Name;
                //    logs_info.Info(log);
                //    memoEdit1.Text = log + Environment.NewLine + memoEdit1.Text;
                //    vEmail.UpdateSendItem(sendItem);
                //    lock (syncRoot) cnt++;
                //});
                SendMail sendmail = new SendMail(ConfigurationManager.AppSettings["api-key"]);
                Parallel.ForEach(items.AsParallel(), new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(txtThread.Text) }, item =>
                {
                    SendResult sendItem = sendmail.SendHtmlMessage(item.From.Split('@')[1] + "", "", item.From, item.To, item.Subject, item.Body,true);
                    sendItem.item_id = item.id;
                    string log = DateTime.Now + "-> Status: " + sendItem.IsSent + ", id:" + sendItem.id + ", MailTo: " + item.To + ", mailFrom: " + item.From + ", Name: " + item.CustomerName;
                    logs_info.Info(log);
                    memoEdit1.Text = log + Environment.NewLine + memoEdit1.Text;
                    DataUtils.UpdateSendItem(sendItem);
                    lock (syncRoot) cnt++;
                });
            }
            catch (Exception ex)
            {
                logs_error.Error("bgw_sendMail_DoWork-", ex);
                memoEdit2.Text += DateTime.Now.ToString() + ex.Message + Environment.NewLine + memoEdit2.Text;
            }
        }

        private void timer_sendMail_Tick(object sender, EventArgs e)
        {
            if (bgw_sendMail.IsBusy) return;
            bgw_sendMail.RunWorkerAsync();
        }

        private void btnCRStop_Click(object sender, EventArgs e)
        {
            btnCRStart.Enabled = true;
            btnCRStop.Enabled = false;
            txtCRSecond.Enabled = true;
            timer_CheckResult.Stop();
        }

        private void btnCRStart_Click(object sender, EventArgs e)
        {
            btnCRStart.Enabled = false;
            btnCRStop.Enabled = true;
            txtCRSecond.Enabled = false;

            timer_CheckResult.Interval = Convert.ToInt32(txtCRSecond.Text) * 1000;
            timer_CheckResult.Start();
        }

        private void timer_CheckResult_Tick(object sender, EventArgs e)
        {
            if (bgw_Check.IsBusy) return;
            bgw_Check.RunWorkerAsync();
        }

        private void bgw_Check_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                Amazon.SQS.AmazonSQSClient client = new Amazon.SQS.AmazonSQSClient(AccessKey, SecrectKey);
                Amazon.SQS.Model.ReceiveMessageRequest SQSrequest = new Amazon.SQS.Model.ReceiveMessageRequest();
                SQSrequest.MaxNumberOfMessages = 10;
                SQSrequest.QueueUrl = "https://sqs.us-east-1.amazonaws.com/063719400628/bounce-queue";
                List<AmazonSesBouncedRecipient> result = AmazonQueues.ProcessQueuedBounce(client.ReceiveMessage(SQSrequest));
                foreach (var item in result)
                {
                    txtCRInfoLogs.Text = "messageId" + item.MessageId + ",EmailAddress:" + item.EmailAddress + Environment.NewLine + txtCRInfoLogs.Text;
                    vEmail.UpdateSendItem(item);
                }
            }
            catch (Exception ex)
            {
                txtCRErrorLogs.Text = DateTime.Now + ":" + ex.Message + Environment.NewLine + txtCRErrorLogs.Text;
            }
        }

        private void bgw_Verify_DoWork(object sender, DoWorkEventArgs e)
        {

        }

        private void bgw_Dashboard_DoWork(object sender, DoWorkEventArgs e)
        {
            LoadDashBoard();
        }

        private void btnVStart_Click(object sender, EventArgs e)
        {
            btnVStart.Enabled = false;
            btnVStop.Enabled = true;
            txtVSecond.Enabled = false;

            timer_Verify.Interval = Convert.ToInt32(txtSecond.Text) * 1000;
            timer_Verify.Start();
        }

        private void btnVStop_Click(object sender, EventArgs e)
        {

            btnVStart.Enabled = true;
            btnVStop.Enabled = false;
            txtVSecond.Enabled = true;
            timer_Verify.Stop();
        }

        private void timer_Verify_Tick(object sender, EventArgs e)
        {

            if (bgw_Verify.IsBusy) return;
            bgw_Verify.RunWorkerAsync();
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (bgw_AmazonEmailVerified.IsBusy) return;

            marqueeProgressBarControl1.Visible = true;
            bgw_AmazonEmailVerified.RunWorkerAsync();
        }

        private void bgw_AmazonEmailVerified_DoWork(object sender, DoWorkEventArgs e)
        {
            List<EmailVerified> list = vEmail.ListEmailVerifiedWithNotification();
            e.Result = list;
        }

        private void bgw_AmazonEmailVerified_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            marqueeProgressBarControl1.Visible = false;
            gridControl1.DataSource = e.Result;
        }

        private void gridView1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                EmailVerified row = (EmailVerified)gridView1.GetFocusedRow();
                if (row != null)
                {
                    setBounceTopicToolStripMenuItem.Visible = !row.isSetBounceTopic;
                    unsetBounceTopicToolStripMenuItem.Visible = row.isSetBounceTopic;
                    setComplainTopicToolStripMenuItem.Visible = !row.isSetComplainTopic;
                    unsetComplainTopicToolStripMenuItem.Visible = row.isSetComplainTopic;
                }
            }
        }

        private void setBounceTopicToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EmailVerified row = (EmailVerified)gridView1.GetFocusedRow();
            if (row != null)
            {
                if (vEmail.SetBounceTopic(row.Email, txtBounceTopic.Text))
                    MessageBox.Show("Set Successfull");
                else MessageBox.Show("Set fail");
            }
        }

        private void unsetBounceTopicToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EmailVerified row = (EmailVerified)gridView1.GetFocusedRow();
            if (row != null)
            {
                if (vEmail.SetBounceTopic(row.Email, null))
                    MessageBox.Show("Set Successfull");
                else MessageBox.Show("Set fail");
            }
        }

        private void setComplainTopicToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EmailVerified row = (EmailVerified)gridView1.GetFocusedRow();
            if (row != null)
            {
                if (vEmail.SetComplainTopic(row.Email, txtComplainTopic.Text))
                    MessageBox.Show("Set Successfull");
                else MessageBox.Show("Set fail");
            }
        }

        private void unsetComplainTopicToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EmailVerified row = (EmailVerified)gridView1.GetFocusedRow();
            if (row != null)
            {
                if (vEmail.SetComplainTopic(row.Email, null))
                    MessageBox.Show("Set Successfull");
                else MessageBox.Show("Set fail");
            }
        }

        private void btnRegister_Click(object sender, EventArgs e)
        {
            if (txtEmailRegister.Text.Trim() == "") { MessageBox.Show("Input Email to Retister"); txtEmailRegister.Focus(); return; }
            if (!Common.EmailTools.IsEmail(txtEmailRegister.Text.Trim())) { MessageBox.Show("Input Email is not format correct"); txtEmailRegister.Focus(); return; }
            if (vEmail.RegisterEmail(txtEmailRegister.Text.Trim()))
            {
                MessageBox.Show("Register OK! Please check mail to confirm.");
            }
        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            frmCheckMail check = new frmCheckMail();
            check.Show();
        }
    }
}